import * as DEFAULT from "@/utils/graph/default";

// import { Type } from "@/utils/graph/Type";

export function TypeManager(ctx) {

  let context = ctx;

  let colorList = [ //默认颜色列表
    "#F56C6C",
    "#E6A23C",
    "#67C23A",
    "#5580ff",
    "#d493ff",
    "#2f84dc",
    "#55bcff",
  ];
  let colorAssignPoi = 0; //分配默认颜色指针

  /**---------------------------------------------------------------------------
   * 初始化type
   */
  this.initType = function(){
    let _this = this;
    context.kgInfo.typeList.forEach(function(type) {
      assignTypeColor(type);
      assignTypeR(type);
    });
    context.kgInfo.nodes.forEach(function(node) {
      node.type = _this.getTypeById(node.typeId);
    });

  }

  /**---------------------------------------------------------------------------
   * 将节点映射为特定类型
   * @param node
   * @param type
   */
  this.mapToTypeList = function(node,type){

    node.type = type;
    node.typeId = type.id;

    type.typedCount++;

  }

  /**---------------------------------------------------------------------------
   * 节点被删除 当前节点类型从typeList卸载
   * @param node
   */
  this.removeFromTypeList = function(node){

    let type = this.getTypeById(node.type.id);
    type.typedCount--;

  }

  /**---------------------------------------------------------------------------
   * 根据名称获取类型
   * @param name
   * @returns {null|*}
   */
  this.getTypeByName = function(name) {
    let typeList = context.kgInfo.typeList;

    for(let i = 0;i<typeList.length;i++){
      if(typeList[i].name == name) return typeList[i];
    }

    return null;
  }

  /**---------------------------------------------------------------------------
   * 根据类型索引获取类型
   * @param index
   */
  this.getTypeByIndex = function(index) {
    if(index<0 || index>=context.kgInfo.typeList.length) return null;
    return context.kgInfo.typeList[index];
  }

  /**---------------------------------------------------------------------------
   * 根据id获取类型
   * @param id
   */
  this.getTypeById = function(id) {
    let typeList = context.kgInfo.typeList;
    for(let i=0;i<typeList.length;i++){
      if(typeList[i].id == id) return typeList[i];
    }
  }

  /**---------------------------------------------------------------------------
   * 添加类型
   * @param type
   * @param remember
   */
  this.addType = function(type,remember=true) {
    context.kgInfo.typeList.push(type);
    assignTypeColor(type);
    assignTypeR(type);

    if(remember) context.historyManager.startRemember();
    context.historyManager.rememberAddType(type);
    if(remember) context.historyManager.endRemember();

    this.informTypeUpdate();

  }

  /**---------------------------------------------------------------------------
   * 删除类型
   * @param typeId
   * @param reshow
   * @param remember
   */
  this.deleteTypeById = function(typeId,reshow=true,remember=true) {
    let typeList = context.kgInfo.typeList;
    for(let i=0;i<typeList.length;i++){
      if(typeList[i].id == typeId){

        if(remember) context.historyManager.startRemember();
        context.historyManager.rememberDeleteType(typeList[i]);

        //删除类型节点
        let nodes = context.elementEditor.getNodesByTypeId(typeId);
        nodes.forEach(function(node,index,nodes) {

          let ifReshow = index===nodes.length-1&&reshow;
          context.elementEditor.deleteNodeById(node.uuid,ifReshow,false);
        });

        typeList.splice(i,1);

        if(remember) context.historyManager.endRemember();
        break;
      }
    }

    this.informTypeUpdate();
  }

  /**---------------------------------------------------------------------------
   *
   * @param oldTypeModal
   * @param newTypeModal
   * @param reshow
   * @param remember
   */
  this.modifyType = function(oldTypeModal,newTypeModal,reshow=true,remember=true) {
    //copy
    let oldTypeObj = this.getTypeById(oldTypeModal.id);
    let oldTypeCopy = JSON.parse(JSON.stringify(oldTypeObj));

    //fix
    oldTypeObj.name = newTypeModal.name;

    context.dataFormatter.modifyProperty(oldTypeObj,newTypeModal,"color","selfColor");
    context.dataFormatter.modifyProperty(oldTypeObj,newTypeModal,"r","selfR");

    //remember
    if(remember) context.historyManager.startRemember();
    context.historyManager.rememberEditType(oldTypeCopy,oldTypeObj);
    if(remember) context.historyManager.endRemember();

    //reshow
    if(reshow){
      let nodes = context.kgInfo.visibleNodes;

      context.dataFormatter.formatNodes(nodes);

      context.drawer.drawNode(nodes);
      context.drawer.drawNodeText(nodes);
      context.drawer.drawButtonGroup(nodes);

      context.eventManager.initNodeEvent();
      context.eventManager.initButtonEvent();

      context.simulation.restartNodesSimulation(nodes);

      context.elementEditor.refreshShow();
    }

    this.informTypeUpdate();
  }

  /**---------------------------------------------------------------------------
   * 通知类型列表更新
   */
  this.informTypeUpdate = function() {
    if(context.update == undefined || context.update == null) context.update = {};
    context.update.typeList = new Date().getTime();
  }

  /**---------------------------------------------------------------------------
   * 分配类型颜色
   * @param type
   */
  function assignTypeColor(type){

    //优先级1：自定义类型颜色
    if(type.selfColor){
      type.color = type.selfColor;
      return;
    }

    //优先级2：上次定义的默认颜色
    if(type.color) return;

    //优先级3：colorList中定义的默认颜色
    if(colorAssignPoi < colorList.length){
      type.color = colorList[colorAssignPoi++];
      return;
    }

    //优先级4：随机颜色
    type.color = randomColor();

  }

  /**---------------------------------------------------------------------------
   * 分配类型半径
   * @param type
   */
  function assignTypeR(type) {

    //优先级1：自定义类型半径
    if(type.selfR){
      type.r = type.selfR;
      return;
    }

    //优先级2：上次定义的默认半径
    if(type.r) return;

    //优先级3：默认半径
    type.r = DEFAULT.R;
  }


  /**---------------------------------------------------------------------------
   * 获取随机颜色
   * @returns {string}
   */
  function randomColor() {
    return "#"+Math.floor(Math.random()*16777215).toString(16);
  }
}